package own.stu.inter.crawler;

import io.netty.channel.nio.NioEventLoopGroup;
import lombok.extern.slf4j.Slf4j;
import org.asynchttpclient.Request;
import org.asynchttpclient.RequestBuilder;
import org.asynchttpclient.Response;
import own.stu.inter.loadbalance.httpclient.AsyncHttpHelper;
import own.stu.inter.loadbalance.httpclient.HttpClient;

import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
public class Crawler {

    BlockingDeque<String> taskDeque = new LinkedBlockingDeque<>();

    private HttpClient client;

    private volatile boolean pageDirListLoadDone = false;

    private AtomicInteger tasks = new AtomicInteger();

    ExecutorService service = Executors.newFixedThreadPool(10);

    FileMergeService mergeService;

    public Crawler() {

        client = new HttpClient(new NioEventLoopGroup());
        client.start();
        log.info("Crawler start .... ");

        mergeService = new FileMergeService("111.txt", this);
    }

    public void shutdown() {
        client.shutdown();
    }

    public static void main(String[] args) {
        final Crawler crawler = new Crawler();
        crawler.downLoad();
//        crawler.shutdown();
    }

    public String getResponseBody(String path) throws ExecutionException, InterruptedException {
        TimeUnit.MILLISECONDS.sleep(300);
        Request request = new RequestBuilder().setUrl(path).build();
        Response response = AsyncHttpHelper.getInstance().executeRequest(request).get();
        return response.getResponseBody();
    }

    public void downLoad() {
        // getDirList to queue
        new Thread(() -> {
            new DirInfoTask(this).getChapterDirList("https://m.ahfgb.com/25/25741/index.html");
            pageDirListLoadDone = true;
        }, "t-dirInfo").start();

        // load to file
        for (int i = 0; i < 10; i++)
            service.submit(new ChapterTask(this));

        service.submit(mergeService);
    }

    public BlockingDeque<String> getTaskDeque() {
        return taskDeque;
    }

    public AtomicInteger getTasks() {
        return tasks;
    }

    public void addDirList(List<String> dirList) {
        this.getTaskDeque().addAll(dirList);
        this.getTasks().getAndAdd(dirList.size());

        this.mergeService.addPageList(dirList);
    }

    public boolean isPageDirListLoadDone() {
        return pageDirListLoadDone;
    }

    public FileMergeService getMergeService() {
        return mergeService;
    }
}
